package service

import (
	"time"

	"gitee.com/night-tc/gobige/logger"
	"gitee.com/night-tc/gobige/msgdef/protomsg"
	"gitee.com/night-tc/gobige/serverMgr"
	"gitee.com/night-tc/gobige/sess"
)

/*
这个是主动链接别的服务器进的消息处理，验证完成后，就会跟换msghandler
用来处理主动连接别的服务器时候，验证逻辑的部分消息
*/
type NetSess_Proc struct {
	Srv   *Service
	Sess  sess.INetSess
	SInfo serverMgr.IServerInfo
}

// 连接别的服务器，对方验证过了
func (this *NetSess_Proc) MsgProc_ClientVerifySucceedRet(msg *protomsg.ClientVerifySucceedRet) {
	srv := this.Srv
	sessmd := this.Sess
	defer func() {
		logger.Infof("Successfully connected ID: %d Type: %d.sess[%s]", sessmd.GetID(), sessmd.GetType(), sessmd.RemoteAddr())
		if !srv.pendingSesses.CompareAndDelete(sessmd.GetID(), sessmd) {
			logger.Infof("ClientVerifySucceedRet delete fail ID: %d Type: %d.", sessmd.GetID(), sessmd.GetType())
		} else {
			logger.Infof("ClientVerifySucceedRet delete success ID: %d Type: %d.", sessmd.GetID(), sessmd.GetType())
		}
		// 延迟调用 OnServerSessConnect
		this.Srv.real.CallDelay(func() {
			this.Srv.real.OnServerSessConnect(sessmd.GetID(), sessmd.GetType())
		})
	}()
	sessmd.SetMsgHandler(srv)
	for {
		if v, ok := srv.clientSesses.LoadOrStore(sessmd.GetID(), sessmd); ok {
			oldsess := v.(sess.INetSess)
			oldsess.Send(&protomsg.UserDuplicateLoginNtf{})
			srv.clientSesses.CompareAndDelete(oldsess.GetID(), oldsess)
			oldsess.Close()
		} else {
			return
		}
	}
}

func (this *NetSess_Proc) MsgProc_ClientVerifyFailedRet(msg *protomsg.ClientVerifyFailedRet) {
	srv := this.Srv
	sessmd := this.Sess
	logger.Infof("ClientVerifyFailedRet ID: %d Type: %d.sess[%s]", sessmd.GetID(), sessmd.GetType(), sessmd.RemoteAddr())
	srv.pendingSesses.CompareAndDelete(sessmd.GetID(), sessmd)
	srv.OnceTimer(time.Second, func(i ...interface{}) {
		/*
			重启获取这个服务器的信息去尝试链接
		*/
		sinfo, err := srv.GetDirMgr().GetServerById(this.SInfo.GetGroupID(), this.SInfo.GetSrvType(), this.SInfo.GetServerID())
		if err != nil {
			logger.Warnf("ClientVerifyFailedRet GetServerById failed ID: %d Type: %d.sess[%s]", sessmd.GetID(), sessmd.GetType(), sessmd.RemoteAddr())
			return
		}
		srv.real.WatchInfoCallBack(sinfo)
	})

}

/*
连接关闭的时候，会自己给自己发一个关闭的消息，这个消息还没有protomsg化
然后在service还有netsess还有user中都需要对这个进行处理
*/
func (this *NetSess_Proc) MsgProc_SessClosed(msg *protomsg.SessClosed) {
	srv := this.Srv
	sessmd := this.Sess
	if !srv.pendingSesses.CompareAndDelete(sessmd.GetID(), sessmd) {
		logger.Infof("SessClosed pendingSesses delete fail ID: %d Type: %d.", sessmd.GetID(), sessmd.GetType())
	} else {
		logger.Infof("SessClosed pendingSesses delete success ID: %d Type: %d.", sessmd.GetID(), sessmd.GetType())
	}

}
